<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { arr2Tree, deepClone } from '@/utils'
import { hashEncrypt } from '@/utils/crypto'
import { findUsers, insertUser, updateUser, deleteUser, findRoles } from '@/api/permission'
import SytTable from '@/components/SytTable/SytTable.vue'
import { ElMessage } from 'element-plus'

let tableThs = ref([
  { title: '用户名', dataIndex: 'username' },
  { title: '角色', dataIndex: 'rolesNames' },
  { title: '昵称', dataIndex: 'nickname' },
  { title: '部门', dataIndex: 'department' },
  { title: '职位', dataIndex: 'position' }
])
let searchUsername = ref('')
let tableData = ref([])
let loading = ref(true)
let currentPage = ref(1)
let pageSize = ref(10)
let total = ref(0)

let dialogFormVisible = ref(false)
let ruleFormRef = ref(null)
let dialogOpenType = ref('')
const rules = ref({
  username: [
    {
      required: true,
      message: '请输入用户名',
      trigger: 'blur'
    }
  ],
  password: [
    {
      required: true,
      message: '请输入密码',
      trigger: 'blur'
    }
  ],
  roles: [
    {
      required: true,
      message: '请输入角色',
      trigger: 'blur'
    }
  ],
  nickname: [
    {
      required: true,
      message: '请输入昵称',
      trigger: 'blur'
    }
  ],
  department: [
    {
      required: true,
      message: '请输入部门',
      trigger: 'blur'
    }
  ],
  position: [
    {
      required: true,
      message: '请输入职位',
      trigger: 'blur'
    }
  ]
})

const rolesData = ref([])
const rolesTreeData = ref([])
const getRolesData = async () => {
  await findRoles().then((res) => {
    if (res.code == 200) {
      rolesData.value = res.data
      rolesTreeData.value = arr2Tree(res.data)
    }
  })
}

// dialog data
let userDataRaw = () => ({
  username: '',
  password: '',
  nickname: '',
  roles: [],
  department: '软件部',
  position: '职员'
})

let userData = ref(userDataRaw())

const getUsersData = async () => {
  const option: any = {
    currentPage: currentPage.value,
    pageSize: pageSize.value
  }

  if (searchUsername.value) option.username = searchUsername.value

  await findUsers(option).then((res) => {
    if (res.code === 200) {
      total.value = res.data.total

      tableData.value = res.data.data.map((user) => {
        user.encrypedPassword = user.password
        user.rolesNames = user.roles.map((role) => rolesData.value.find((r) => r.id == role)?.name)

        return user
      })
    }
  })
}

const initData = async () => {
  await getRolesData()
  await getUsersData()

  loading.value = false
}

const openDialogByInsert = () => {
  dialogOpenType.value = '添加账号'
  dialogFormVisible.value = true

  userData.value = userDataRaw()
}

const openDialogByEdit = (row) => {
  dialogOpenType.value = '编辑账号'
  dialogFormVisible.value = true
  userData.value = deepClone(row)
}

const toInsertUser = async () => {
  let data = Object.assign({}, userData.value)
  data.password = await hashEncrypt(data.password)
  insertUser(data).then((res) => {
    if (res.code == 200) {
      ElMessage({ type: 'success', message: '添加成功' })
      initData()
    }
  })
}

const toUpdateUser = async () => {
  let data: any = Object.assign({}, userData.value)
  if (data.password != data.encrypedPassword) data.password = await hashEncrypt(data.password)
  Reflect.deleteProperty(data, 'encrypedPassword')

  updateUser(data).then((res) => {
    if (res.code == 200) {
      initData()
      ElMessage({ type: 'success', message: '编辑成功' })
    }
  })
}

const toDeleteUser = (row) => {
  if (row.id) {
    deleteUser({ id: row.id }).then((res) => {
      if (res.code == 200) {
        initData()
        ElMessage({ type: 'success', message: '删除成功' })
      }
    })
  } else ElMessage({ type: 'error', message: '不存在的id' })
}

const submitForm = (formEl) => {
  if (!formEl) return
  formEl.validate((valid) => {
    if (valid) {
      if (dialogOpenType.value === '添加账号') toInsertUser()
      else toUpdateUser()

      dialogFormVisible.value = false
    } else {
      console.log('验证失败!')
    }
  })
}
// 分页
const handlePaginationChange = (currentP, pSize) => {
  currentPage.value = currentP
  pageSize.value = pSize

  initData()
}

onMounted(() => {
  initData()
})
</script>

<template>
  <div v-loading="loading" element-loading-text="加载中...">
    <div class="tools">
      <el-input
        v-model="searchUsername"
        placeholder="输入用户名查询"
        class="search"
        clearable
        @blur="initData"
      />
      <el-button @click="openDialogByInsert">添加账号</el-button>
    </div>

    <SytTable :columns="tableThs" :data="tableData">
      <template #operations="scope">
        <el-button
          size="small"
          type="primary"
          icon="Edit"
          circle
          @click="openDialogByEdit(scope.row)"
        />
        <el-popconfirm
          :title="`确定删除 ${scope.row.username} 账号?`"
          confirm-button-text="确定"
          cancel-button-text="取消"
          icon="InfoFilled"
          icon-color="var(--el-color-warning)"
          @confirm="toDeleteUser(scope.row)"
        >
          <template #reference>
            <el-button size="small" type="danger" icon="Delete" circle />
          </template>
        </el-popconfirm>
      </template>
    </SytTable>

    <el-pagination
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      :page-sizes="[10, 20, 30, 40, 50, 100]"
      class="pagination"
      size="small"
      background
      @change="handlePaginationChange"
    />

    <el-dialog v-model="dialogFormVisible" :title="dialogOpenType" width="350px">
      <el-form ref="ruleFormRef" :model="userData" :rules="rules" size="large" class="w-full">
        <el-form-item label="账号" prop="username">
          <el-input
            v-model="userData.username"
            placeholder="用户名"
            prefix-icon="user"
            :disabled="dialogOpenType == '编辑账号'"
          />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input
            v-model="userData.password"
            placeholder="密码"
            prefix-icon="lock"
            type="password"
          />
        </el-form-item>
        <el-form-item label="角色" prop="roles">
          <el-tree-select
            v-model="userData.roles"
            :data="rolesTreeData"
            :props="{ label: 'name', value: 'id' }"
            check-strictly
            multiple
            :render-after-expand="false"
            style="width: 240px"
          />
        </el-form-item>
        <el-form-item label="昵称" prop="nickname">
          <el-input v-model="userData.nickname" placeholder="昵称" />
        </el-form-item>
        <el-form-item label="部门" prop="department">
          <el-input v-model="userData.department" placeholder="部门" />
        </el-form-item>
        <el-form-item label="职位" prop="position">
          <el-input v-model="userData.position" placeholder="职位" />
        </el-form-item>
        <el-form-item>
          <el-button class="w-full" type="primary" @click="submitForm(ruleFormRef)">
            保存
          </el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<style scoped>
.tools {
  display: flex;
  justify-content: flex-end;
  margin-bottom: 10px;
}

.search {
  width: 150px;
  margin-right: 10px;
}

.pagination {
  margin-top: 10px;
}
</style>
